home *** CD-ROM | disk | FTP | other *** search
-
- #import "Utilities.h"
- #import "TreeView.h"
-
- #define LEFTARROWKEY 172
- #define RIGHTARROWKEY 174
- #define UPARROWKEY 173
- #define DOWNARROWKEY 175
- #define PUSHKEY 0x3
- #define BACKSPACEKEY 0x7f
-
- @interface TreeView(PrivateMethods)
-
- - updateCanvasPos:(NXCoord)xPos :(NXCoord)yPos;
-
- @end
-
- @implementation TreeView
-
- - initFrame:(const NXRect *)frameRect
- {
- [super initFrame:frameRect];
- xTimes = 1;
- yTimes = 1;
- canvasRect = *frameRect;
- canvasPath = nil;
- [self updateCanvasPos:0 :0];
- [[self setClipping:NO] setFlipped:YES];
- linkPath = nil;
- hitPath = nil;
- agent = nil;
- nodeList = [[List allocFromZone:[self zone]] init];
- pbConversion = NO;
- pbTree = nil;
- return self;
- }
-
- - free
- {
- if(linkPath)
- [linkPath free];
- if(hitPath)
- [hitPath free];
- [nodeList free];
- return [super free];
- }
-
- - (BOOL)lockFocus
- {
- BOOL aBOOL;
- float rot,gruen,blau;
-
- if(NXDrawingStatus == NX_DRAWING){
- aBOOL = [super lockFocus];
- PScurrentlinewidth(&drawState.linewidth);
- PScurrentrgbcolor(&rot,&gruen,&blau);
- drawState.color = NXConvertRGBToColor(rot,gruen,blau);
- drawState.font = nil;
- return aBOOL;
- } else
- return [super lockFocus];
- }
-
- - drawSelf:(const NXRect *)r :(int)count
- {
- if(count == 1){
- [self drawYourSelf:r];
- } else {
- [self drawYourSelf:&r[1]];
- [self drawYourSelf:&r[2]];
- }
- return self;
- }
-
- - drawYourSelf:(const NXRect *)r
- {
- id tree;
- int i,j;
-
- PSsetgray(NX_WHITE);
- NXRectFill(r);
- drawState.color = NX_COLORWHITE;
- if(NXDrawingStatus == NX_DRAWING){
- PSrectviewclip(r->origin.x,r->origin.y,r->size.width,r->size.height);
- PSsetgray(NX_LTGRAY);
- PSsetlinewidth(0.15);
- drawState.color = NX_COLORLTGRAY;
- drawState.linewidth = 0.15;
- for(i = 0;i <= xTimes;i++)
- for(j = 0;j <= yTimes;j++){
- [self updateCanvasPos:i * NX_WIDTH(&canvasRect) :j * NX_HEIGHT(&canvasRect)];
- [canvasPath send:dps_ustroke cached:YES];
- }
- }
- if(!pbConversion)
- tree = [agent tree];
- else
- tree = pbTree;
- if(tree)
- [self drawTree:tree inRect:r];
- if(NXDrawingStatus == NX_DRAWING)
- PSinitviewclip();
- return self;
- }
-
- - drawTree:tree inRect:(const NXRect *)r
- {
- int i;
- BOOL knobs, attachments;
-
- [tree layout];
- if(!linkPath)
- linkPath = [[UPath allocFromZone:[self zone]] init];
- [linkPath resetFill];
- [nodeList empty];
- if(NXDrawingStatus == NX_PRINTING)
- [tree involved:NULL addTo:nodeList link:linkPath];
- else
- [tree involved:r addTo:nodeList link:linkPath];
- for(i = 0; i < [nodeList count];i++)
- [[nodeList objectAt:i] drawNodeShadow:&drawState];
- if([tree child] && ![tree zipped]){
- PSsetgray(NX_BLACK);
- drawState.color = NX_COLORBLACK;
- PSsetlinewidth(0.15);
- drawState.linewidth = 0.15;
- [linkPath send:dps_ustroke cached:NO];
- }
- for(i = 0; i < [nodeList count];i++)
- [[nodeList objectAt:i] drawNodeEnding:&drawState];
- for(i = 0; i < [nodeList count];i++)
- [[nodeList objectAt:i] drawNodeFill:&drawState];
- if(NXDrawingStatus == NX_DRAWING){
- knobs = YES;
- attachments = [agent showMarker];
- } else
- knobs = attachments = NO;
- for(i = 0; i < [nodeList count];i++)
- [[nodeList objectAt:i] drawNodeOutline:&drawState knobs:knobs];
- for(i = 0; i < [nodeList count];i++)
- [[nodeList objectAt:i] drawNodeCellsInView:self attachments:attachments];
- return self;
- }
-
- - mouseDown:(NXEvent *)event
- {
- NXPoint p;
- NXRect redrawRect, textFrame;
- NXSize maxTextSize;
- id selectedNode,lastSelected,tree;
- id retval, fe = nil;
- BOOL hitAttach, fieldResponder = NO;
-
- p = event->location;
- [self convertPoint:&p fromView:nil];
- [window disableFlushWindow];
- [self lockFocus];
- tree = [agent tree];
- if(tree){
- if(!hitPath)
- hitPath = [[HitPath allocFromZone:[self zone]] init];
- [hitPath movePathToPoint:&p];
- selectedNode = [tree hit:hitPath];
- if(selectedNode){
- lastSelected = [agent declareSelection:selectedNode];
- if(selectedNode != lastSelected){
- [selectedNode getBounds:&redrawRect];
- [self drawSelf:&redrawRect :1];
- [self scrollRectToVisible:&redrawRect];
- if(lastSelected){
- [lastSelected setSelected:YES];
- [lastSelected getBounds:&redrawRect];
- [lastSelected setSelected:NO];
- [self drawSelf:&redrawRect :1];
- }
- }
- if(event->data.mouse.click >= 2){
- [window endEditingFor:self];
- fe = [window getFieldEditor:YES for:self];
- [fe setFont:[selectedNode font]];
- [fe setCharFilter:NXFieldFilter];
- [fe setFontPanelEnabled:NO];
- [fe setMonoFont:YES];
- [fe setOpaque:YES];
- [selectedNode getTextFrame:&textFrame];
- [fe setMinSize:&(textFrame.size)];
- maxTextSize.width = bounds.size.width;
- maxTextSize.height = textFrame.size.height;
- [fe setMaxSize:&maxTextSize];
- [fe setFrame:&textFrame];
- [fe setHorizResizable:YES];
- [fe setText:[selectedNode label]];
- [fe selectAll:self];
- [fe setAlignment:NX_CENTERED];
- [fe unscript:self];
- [fe setVertResizable:NO];
- [fe setDelegate:selectedNode];
- [self addSubview:fe];
- p.x = textFrame.origin.x;
- p.y = textFrame.origin.y;
- [self convertPoint:&p toView:nil];
- event->location = p;
- [fe mouseDown:event];
- fieldResponder = YES;
- }
- } else if([agent showMarker]){
- selectedNode = [tree hitAttachment:&p :&hitAttach];
- if(selectedNode){
- [window reenableFlushWindow];
- if(hitAttach)
- retval = [selectedNode activateAttachment:event inView:self];
- else
- retval = [selectedNode activateSound:event inView:self];
- [window disableFlushWindow];
- if(retval){
- lastSelected = [agent declareSelection:selectedNode];
- if(selectedNode != lastSelected){
- [selectedNode getBounds:&redrawRect];
- [self drawSelf:&redrawRect :1];
- if(lastSelected){
- [lastSelected setSelected:YES];
- [lastSelected getBounds:&redrawRect];
- [lastSelected setSelected:NO];
- [self drawSelf:&redrawRect :1];
- }
- }
- }
- } else {
- lastSelected = [agent declareSelection:nil];
- if(lastSelected){
- [lastSelected setSelected:YES];
- [lastSelected getBounds:&redrawRect];
- [lastSelected setSelected:NO];
- [self drawSelf:&redrawRect :1];
- }
- }
- }
- }
- [self unlockFocus];
- [window reenableFlushWindow];
- [window flushWindow];
- if(fieldResponder)
- [window makeFirstResponder:fe];
- else
- [window makeFirstResponder:self];
- return self;
- }
-
- - keyDown:(NXEvent *)event
- {
- id selectedNode = nil,lastSelected,tree,fe;
- NXEvent *eptr = event;
- NXRect redrawRect, textFrame;
- NXSize maxTextSize;
-
- if(eptr->data.key.charSet == NX_SYMBOLSET){
- lastSelected = [agent currentNode];
- if(!lastSelected)
- return self;
- [window disableFlushWindow];
- [self lockFocus];
- switch(eptr->data.key.charCode){
- case LEFTARROWKEY:
- selectedNode = [lastSelected parent];
- break;
- case RIGHTARROWKEY:
- if(![lastSelected zipped])
- selectedNode = [lastSelected child];
- break;
- case UPARROWKEY:
- tree = [lastSelected parent];
- if(tree){
- tree = [tree child];
- if(tree == lastSelected)
- selectedNode = nil;
- else {
- while([tree sibling] != lastSelected)
- tree = [tree sibling];
- selectedNode = tree;
- }
- } else
- selectedNode = nil;
- break;
- case DOWNARROWKEY:
- selectedNode = [lastSelected sibling];
- break;
- default:
- break;
- }
- if(selectedNode){
- [agent declareSelection:selectedNode];
- [selectedNode getBounds:&redrawRect];
- [self drawSelf:&redrawRect :1];
- [self scrollRectToVisible:&redrawRect];
- [lastSelected setSelected:YES];
- [lastSelected getBounds:&redrawRect];
- [lastSelected setSelected:NO];
- [self drawSelf:&redrawRect :1];
- }
- [self unlockFocus];
- [window reenableFlushWindow];
- [window flushWindow];
- [window makeFirstResponder:self];
- } else if(eptr->data.key.charSet == NX_ASCIISET && eptr->data.key.charCode == PUSHKEY){
- lastSelected = [agent currentNode];
- if(!lastSelected)
- return self;
- [self lockFocus];
- [window endEditingFor:self];
- fe = [window getFieldEditor:YES for:self];
- [fe setFont:[lastSelected font]];
- [fe setCharFilter:NXFieldFilter];
- [fe setFontPanelEnabled:NO];
- [fe setMonoFont:YES];
- [fe setOpaque:YES];
- [lastSelected getTextFrame:&textFrame];
- [fe setMinSize:&(textFrame.size)];
- maxTextSize.width = bounds.size.width;
- maxTextSize.height = textFrame.size.height;
- [fe setMaxSize:&maxTextSize];
- [fe setFrame:&textFrame];
- [fe setHorizResizable:YES];
- [fe setText:[lastSelected label]];
- [fe setAlignment:NX_CENTERED];
- [fe unscript:self];
- [fe setVertResizable:NO];
- [fe setDelegate:lastSelected];
- [self addSubview:fe];
- [fe selectAll:self];
- [self unlockFocus];
- [window flushWindow];
- [window makeFirstResponder:fe];
- } else if(eptr->data.key.charSet == NX_ASCIISET && eptr->data.key.charCode == BACKSPACEKEY)
- [agent delete:self];
- return self;
- }
-
- - (BOOL)checkResize:(const NXRect *)r for:tree
- {
- NXRect treeBounds;
- NXCoord dlx, dly, dux, duy;
- BOOL result = NO;
- NXPoint p;
- int tx,ty;
-
- [tree layout];
- [tree getTreeBounds:&treeBounds lowerWidth:&dlx lowerHeight:&dly];
- dux = NX_WIDTH(&treeBounds) - dlx;
- duy = NX_HEIGHT(&treeBounds) - dly;
- [self convertRect:&treeBounds toView:superview];
- if(r){
- [self sizeTo:NX_WIDTH(r) :NX_HEIGHT(r)];
- canvasRect = *r;
- xTimes = yTimes = 1;
- result = YES;
- }
- tx = ceil(NX_WIDTH(&treeBounds) / NX_WIDTH(&canvasRect));
- ty = ceil(NX_HEIGHT(&treeBounds) / NX_HEIGHT(&canvasRect));
- if(ty != yTimes || tx != xTimes){
- xTimes = tx;
- yTimes = ty;
- [self sizeTo:NX_WIDTH(&canvasRect) * xTimes :NX_HEIGHT(&canvasRect) * yTimes];
- result = YES;
- }
- if(xTimes == 1)
- p.x = dlx + (NX_WIDTH(&bounds) - dlx - dux) / 2;
- else
- p.x = dlx + 3;
- if(yTimes == 1)
- p.y = dly + (NX_HEIGHT(&bounds) - dly - duy) / 2;
- else
- p.y = dly + 3;
- [tree setPositionTo:&p];
- return result;
- }
-
- - setAgent:aAgent
- {
- agent = aAgent;
- return self;
- }
-
- - agent
- {
- return agent;
- }
-
- - writePSToStream:(NXStream *)stream usingTree:aTree
- {
- NXRect bbox;
- NXCoord dl, du;
-
- if(stream){
- pbConversion = YES;
- pbTree = aTree;
- [aTree getTreeBounds:&bbox lowerWidth:&dl lowerHeight:&du];
- [self copyPSCodeInside:&bbox to:stream];
- pbConversion = NO;
- pbTree = nil;
- }
- return self;
- }
-
- - (BOOL)zoomTo:(float)zoomX :(float)zoomY
- {
- if(agent)
- [agent setDocScale:zoomX];
- return NO;
- }
-
- - (BOOL)acceptsFirstResponder
- {
- return YES;
- }
-
- - (int)canvasX
- {
- return xTimes;
- }
-
- - (int)canvasY
- {
- return yTimes;
- }
-
- - (BOOL)knowsPagesFirst:(int *)firstPageNum last:(int *)lastPageNum
- {
- *lastPageNum = xTimes * yTimes;
- return YES;
- }
-
- - (BOOL)getRect:(NXRect *)theRect forPage:(int)page
- {
- int row, col;
-
- if(page < 1 || page > xTimes * yTimes)
- return NO;
- page--;
- row = page / xTimes;
- col = page % xTimes;
- theRect->origin.x = col * NX_WIDTH(&canvasRect);
- theRect->origin.y = row * NX_HEIGHT(&canvasRect);
- theRect->size.width = NX_WIDTH(&canvasRect);
- theRect->size.height = NX_HEIGHT(&canvasRect);
- return YES;
- }
-
- - printPSCode:sender
- {
- float printScaleFactor;
-
- printScaleFactor = [[agent printInfo] scalingFactor];
- if(printScaleFactor != 1)
- [self scale:printScaleFactor :printScaleFactor];
- [super printPSCode:sender];
- if(printScaleFactor != 1)
- [self scale: 1 / printScaleFactor :1 / printScaleFactor];
- return self;
- }
-
- @end
-
-
- @implementation TreeView(PrivateMethods)
-
- - updateCanvasPos:(NXCoord)xPos :(NXCoord)yPos
- {
- canvasRect.origin.x = xPos;
- canvasRect.origin.y = yPos;
- if(!canvasPath){
- canvasPath = [[UPath allocFromZone:[self zone]] init];
- [canvasPath moveto:canvasRect.origin.x :canvasRect.origin.y];
- [canvasPath rlineto:canvasRect.size.width :0.0];
- [canvasPath rlineto:0.0 :canvasRect.size.height];
- [canvasPath rlineto:-canvasRect.size.width :0.0];
- [canvasPath rlineto:0.0 :-canvasRect.size.height];
- } else {
- canvasPath->bbox[0] = canvasRect.origin.x;
- canvasPath->bbox[1] = canvasRect.origin.y;
- canvasPath->bbox[2] = canvasRect.origin.x + canvasRect.size.width;
- canvasPath->bbox[3] = canvasRect.origin.y + canvasRect.size.height;
- canvasPath->params[0] = canvasRect.origin.x;
- canvasPath->params[1] = canvasRect.origin.y;
- canvasPath->params[2] = canvasRect.size.width;
- canvasPath->params[3] = 0.0;
- canvasPath->params[4] = 0.0;
- canvasPath->params[5] = canvasRect.size.height;
- canvasPath->params[6] = -canvasRect.size.width;
- canvasPath->params[7] = 0.0;
- canvasPath->params[8] = 0.0;
- canvasPath->params[9] = -canvasRect.size.height;
- }
- return self;
- }
-
- @end
-
-